///////////////////////////////////////////////////////////////////////////
//
// Spring Engine Source File.
// Copyright (C), Dengtao 2011-2021
// ----------------------------------------------------------------------
// File name:   SfNotificationCenter.h
// Version:     v1.0.0
// Created:     2013/06/21 22:16 by dengtao
// Compilers:   Visual Studio 2008
// Description: 
// ----------------------------------------------------------------------
// History:
//
///////////////////////////////////////////////////////////////////////////

#ifndef _SfNotificationCenter_H_
#define _SfNotificationCenter_H_

#include "SfNotificationExtraInfo.h"
#include "SfNotification.h"
#include "SfSharedSingleton.h"
#include "SfDelegate.h"
#include <map>
#include <list>

namespace Sunflower
{

typedef Delegate<void (const Notification&)> NotificationHandleDelegate;

//////////////////////////////////////////////////////////////////////////
//Summary:
//	notification center.
//////////////////////////////////////////////////////////////////////////
class NotificationCenter : public SharedSingleton<NotificationCenter>
{
public:
public:
	//
	//Summary:
	//	Constructor.
	NotificationCenter();

	//
	//Summary:
	//	Destructor.
	virtual ~NotificationCenter();
	
	//
	//Summary:
	//	Add a notification observer.
	void AddObserver(unsigned int notificationId, 
		const NotificationHandleDelegate& nhd);

	//
	//Summary:
	//	Remove a notification observer.
	void RemoveObserver(unsigned int notificationId, 
		NotificationHandleDelegate& nhd);

	//
	//Summary:
	//	Remove all notification observers.
	void RemoveAllObservers();

	//Summary:
	//	
	//
	//Summary:
	//	Post immediate notification.
	void PostNotification(const Notification& notification);

	//
	//Summary:
	//	Post delayed notification.
	void PostDelayedNotification(const Notification& notification, 
		float delayTime);

	//
	//Summary:
	//	Update time.
	virtual void UpdateTime(float deltaTime);

	//
	//Summary:
	//	Update all delayed notifications.
	virtual void UpdateAllDelayedNotifications();

protected:
	NotificationCenter(const NotificationCenter&);
	NotificationCenter& operator =(const NotificationCenter&);

	struct DelayedNotification
	{
		DelayedNotification(const Notification& notification, float delayTime,
			float postTime)
			: m_Notification(notification)
			, m_DelayTime(delayTime)
			, m_PostTime(postTime)
		{
		}

		float m_PostTime;
		float m_DelayTime;
		Notification m_Notification;
	};

protected:
	typedef std::list<DelayedNotification> DelayedNotificationList;
	typedef DelayedNotificationList::iterator DelayedNotificationListIterator;
	typedef DelayedNotificationList::const_iterator
		DelayedNotificationListConstIterator;

	typedef std::list<NotificationHandleDelegate> ObserverList;
	typedef ObserverList::iterator ObserverListIterator;
	typedef ObserverList::const_iterator ObserverListConstIterator;

	typedef std::map<unsigned int, ObserverList> ObserverMap;
	typedef ObserverMap::iterator ObserverMapIterator;
	typedef ObserverMap::const_iterator ObserverMapConstIterator;

	//
	//Summary:
	//	find observer iterator.
	ObserverListIterator _FindObserverInList(ObserverList& ol,
		const NotificationHandleDelegate& nhd);
	ObserverListConstIterator _FindObserverInList(const ObserverList& ol,
		const NotificationHandleDelegate& nhd) const;

	//
	//Summary:
	//	_PostNotificationToObserversInList
	void _PostNotificationToObserversInList(ObserverList& ol, 
		const Notification& notification);

private:
	ObserverMap m_Observers;
	float m_LastUpdateTime;
	DelayedNotificationList m_DelayedNotifications;
};
} // end of namespace Sunflower

#endif
